架构图

1、 Fabric使用couchdb的优势

Fabric的状态存储支持可插拔的模式,兼容LevelDB、CouchDB等存储。Fabric使用CouchDB作为状态存储与其他数据库相比具有较多优势:

  • CouchDB是一种NoSQL解决方案。它是一个面向文档的数据库,其中文档字段存储为键值映射。字段可以是简单的键值对、列表或映射。除了支持类似LevelDB的键控/合成键/键范围查询之外,CouchDB还支持完整的数据富查询功能,比如针对整个区块链数据的非键查询,因为它的数据内容是以JSON格式存储的,并且是完全可查询的。因此,CouchDB可以满足LevelDB不支持的许多用例的链代码、审计和报告需求。
  • CouchDB还可以增强区块链中的遵从性和数据保护的安全性。因为它能够通过筛选和屏蔽事务中的各个属性来实现字段级别的安全性,并且只在需要时授权只读权限。
  • CouchDB属于CAP定理的ap类型(可用性和分区公差)。它使用具有最终一致性的主-主复制模型。更多信息可以在CouchDB文档的最终一致性页面上找到。然而,在每个fabric对等点下,没有数据库副本,对数据库的写操作保证一致和持久(而不是最终的一致性)。
  • CouchDB是Fabric的第一个外部可插入状态数据库,可以而且应该有其他外部数据库选项。例如,IBM为其区块链启用关系数据库。还可能需要cp类型(一致性和分区容忍度)的数据库,以便在不保证应用层的情况下实现数据一致性。

2、修改peer节点的docker-compose配置文件

在配置文件中增加couchdb服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
couchdb0.org1.example.com:
container_name: couchdb0.org1.example.com
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984"
networks:
- hello

在peer节点服务中添加环境变量配置

1
2
3
4
5
6
7
8
9
environment: 
# CouchDB
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org1.example.com:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

networks:
hello:
services:
couchdb0.org1.example.com:
container_name: couchdb0.org1.example.com
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984"
networks:
- hello
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_LOCALMSPID=Org1MSP
#
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
#
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051
#
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=helloworld_hello

#- CORE_LOGGING_LEVEL=ERROR
- CORE_LOGGING_LEVEL=DEBUG
#TLS
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# CouchDB
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org1.example.com:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=

working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
ports:
- 7051:7051
- 7052:7052
- 7053:7053
depends_on:
- couchdb0.org1.example.com
# extra_hosts:
# - "orderer.example.com:192.168.235.100"
networks:
- hello

cli_peer0_org1:
container_name: cli_peer0_org1
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli_peer0_org1

- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
- ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer

volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/helloworld/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
# extra_hosts:
# - "orderer.example.com:192.168.235.100"
# - "peer0.org1.example.com:192.168.235.101"
# - "peer1.org1.example.com:192.168.235.102"
# - "peer0.org2.example.com:192.168.235.103"
# - "peer1.org2.example.com:192.168.235.104"
networks:
- hello

3.启动区块链节点并验证

重新启动区块链节点,并重新创建通道、加入通道、安装链码。

1
2
3
4
5
6
7
8
9
10
11
12
13
#创建通道
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/mychannel.tx --tls --cafile $ORDERER_CA
#加入通道
peer channel join -b mychannel.block

#安装链码
peer chaincode install -n mycc -p github.com/hyperledger/fabric/helloworld/chaincode/go/helloworld/ -v 1.0

#实例化链码
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C mychannel -n mycc -v 1.0 -c '{"Args":["a","hello"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"

#查询链码
peer chaincode query -C mychannel -n mycc -c '{"function":"get","Args":["a"]}'

这时我们可以通过couchdb 图形界面看到多了出来几个通道和链码相关的数据库。

couchdb

要看mychannel_mycc数据库下有哪些数据,还可以使用下面命令:
curl http://localhost:5984/mychannel_mycc/_all_docs
可以看到我运行了一些ChainCode后的State DATABASE结果:
couchdb